using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using xiushen.Domain;

namespace xiushen.Tests
{
  
    public abstract class DownLoadFile
    {

        protected DownLoadFile()
        {
            a_pattern = @"(?<=<a[^<>]+href=""?)[^""<>]+(?=""?[^<>]*>)";
            a_title = @"(?<=<a+[^<>]+>)[^""<>]+(?=[</a>])";
        }
        protected string MatchData(MatchStructure m)
        {
            var line = m.line;
            var index = line.IndexOf(m.fisrtMath);
            var firstIndex = line.IndexOf(m.secondMatch, index);
            var nextIndex = line.IndexOf(m.lastMatch);
            return line.Substring(firstIndex + 1, nextIndex - firstIndex - 1);
        }
        public Dictionary<string, IList<Category>> datas = new Dictionary<string, IList<Category>>();
        public Dictionary<string, IList<Book>> bookList = new Dictionary<string, IList<Book>>();
        public Dictionary<string, IList<Chapter>> chapterList = new Dictionary<string, IList<Chapter>>();
        protected XiushenRepository _repository = new XiushenRepository();
        protected string a_pattern { get; set; }
        protected string a_title { get; set; }
        protected string b_pattern { get; set; }
        protected abstract void HandleLines(string line);
        public abstract void DownLoadAllBookList(string url, string category);
        public abstract Book DownLoadBookChapters(string url, string book, string category);
        private string serriazeCategory = @"d:\category.bin";
        private string serriazeBook = @"d:\seriBook.bin";
        private string serriazeChapter = @"d:\seariChapter.bin";
        public void SerarializeToFile()
        {
            using (System.IO.FileStream fs = new System.IO.FileStream(serriazeCategory, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                b.Serialize(fs, datas);
                fs.Close();
            }
            using (System.IO.FileStream fs = new System.IO.FileStream(serriazeBook, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                b.Serialize(fs, bookList);
                fs.Close();
            }
            using (System.IO.FileStream fs = new System.IO.FileStream(serriazeChapter, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                b.Serialize(fs, chapterList);
                fs.Close();
            }
        }
        public void BackToData()
        {

            using (System.IO.FileStream ds = new System.IO.FileStream(serriazeCategory, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                datas = bf.Deserialize(ds) as Dictionary<string, IList<Category>>;
            }
            using (System.IO.FileStream ds = new System.IO.FileStream(serriazeBook, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                bookList = bf.Deserialize(ds) as Dictionary<string, IList<Book>>;
            }
            using (System.IO.FileStream ds = new System.IO.FileStream(serriazeChapter, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                chapterList = bf.Deserialize(ds) as Dictionary<string, IList<Chapter>>;
            }
        }
        public void DownLoadBookList(string urls)
        {
            //var url = new Uri(urls);
            //Spider.Initialize();
            //var content = Spider.getHTML3(url);
            //StreamReader reader = new StreamReader(new MemoryStream(content), Encoding.Default);
            //while (!reader.EndOfStream)
            //{
            //    var line = reader.ReadLine();
            //    if (line.Contains("<div class=\"dleft\">"))
            //    {
            //        break;
            //    }
            //    HandleLines(line);
            //}
        

            //foreach (var data in datas)
            //{
            //    foreach (var v in data.Value)
            //    {
            //         DownLoadAllBookList(v.URL, v.Name);
            //        //Console.WriteLine(v.URL + v.Name);
            //    }
            //}

            //foreach (var d in bookList)
            //{

            //    using (var writer = new StreamWriter(@"d:\log2.txt", true))
            //    {
            //        foreach (var ex in d.Value)
            //        {
            //            var book = DownLoadBookChapters(ex.URL, ex.Name, d.Key);
            //            ex.DirectContent = book.DirectContent;
            //            ex.Description = book.Description;
            //            writer.WriteLine(d.Key + ex.URL + ex.Name);

            //        }
            //    }

            //}
            //SerarializeToFile();
            BackToData();
            SaveDatas();
        }

        public void SaveDatas()
        {

            //var result = _repository.InsertCategory(datas.Keys.ToArray(), null);
            //foreach (var data in datas)
            //{
            //    _repository.InsertCategory(data.Value.Select(r => r.Name).ToArray(), result[data.Key]);
            //}
            using (var errorSave = new StreamWriter(@"d:\errorSave.txt", true))
            {
                var categorys = _repository.QueryAll<Category>().ToDictionary(r => r.Name, e => e.ID);
                foreach (var book in bookList)
                {
                    foreach (var b in book.Value)
                    {
                        try
                        {
                            b.CategoryID = categorys[book.Key];
                            var id = _repository.InsertBook(b);
                            int chapterId = 0;
                            if (chapterList.ContainsKey(b.URL))
                            {
                                foreach (var cs in chapterList[b.URL])
                                {
                                    cs.BookID = id;
                                    cs.ID = ++chapterId;
                                    cs.CategoryID = b.CategoryID;
                                    _repository.Insert(cs);

                                }
                            }
                        }
                        catch (Exception)
                        {
                            errorSave.WriteLine(book.Key + b.URL + b.Name);
                               
                        }

                    }
                }
            }
          


        }

       
    }
}